#ifndef __NORMALJUDGE_HPP__
#define __NORMALJUDGE_HPP__

#include "baseJudge.hpp"
#include <type_traits>

class NormalJudge : public CorrectOutComponent, public JudgeType<NormalJudge> {
public:
    NormalJudge();
    ProcessStatus init(run_code_context_t<NormalJudge>& context);
    template <class Event>
    run_code_event_t next_event(Event e);
};

template <class Event>
run_code_event_t NormalJudge::next_event(Event e) {
    using std::is_same_v;
    const auto& context = *this->belong_context;
    if constexpr (is_same_v<Event, initial_event>) {
        if (context.get_latest_status().result != RUN_OK) {
            return end_event{};
        }
        return std_code_compile_event{};
    }
    if constexpr (is_same_v<Event, std_code_compile_event>) {
        return user_code_compile_event{};
    }
    if constexpr (is_same_v<Event, user_code_compile_event>) {
        if (context.get_latest_status().result != RUN_OK) {
            return end_event{};
        }
        return std_code_run_event{};
    }
    if constexpr (is_same_v<Event, std_code_run_event>) {
        return user_code_run_event{};
    }
    if constexpr (is_same_v<Event, user_code_run_event>) {
        if (context.get_latest_status().result != RUN_OK) {
            return calculate_result_event{};
        }
        return text_compare_event{};
    }
    if constexpr (is_same_v<Event, text_compare_event>) {
        return calculate_result_event{};
    }
    if constexpr (is_same_v<Event, calculate_result_event>) {
        // all test example is tested
        if (inFiles.size() == example_index) {
            return end_event{};
        // latest test is error
        } else if (context.result.passExample != context.result.testExample) {
            int ruler = context.params.ruler;
            // OI CONTENT continue test
            if (ruler == OI_CONTENT) {
            // ACM CONTENT exit
            } else if (ruler == ACM_CONTENT) {
                return end_event{};
            }
        }

        return std_code_run_event{};
    }
    return end_event{};
}

#endif /* __NORMALJUDGE_HPP__ */
